package controller.dispatchers;

import java.util.concurrent.LinkedBlockingQueue;

import controller.ModelDummy;
import model.GameCommand;

/*
 * This implements the AbstractDispatcher interface and defines
 * the wrapper/accessor functionality for a LinkedBlockingQueue, 
 * parameterized with GameCommand objects, which it dispatches to the
 * model. 
 * 
 * ModelDispatcher
    * Reasons for Existence: to organize and queue commands for the model 
    * created by listener threads
    * Team Members Responsible
          o Implementation: Nik, Tait
          o Testing: Nik, Tait 
 */
public class ModelDispatcher implements AbstractDispatcher 
{
	/*
	 *  THIS NEEDS TO BE CHANGED!!
	 */
	private ModelDummy m;								// reference to the Model
	private LinkedBlockingQueue<GameCommand> queue; 	// GameCommand queue
	
	// Constructor
	public ModelDispatcher(ModelDummy m) // USES a DUMMY OBJECT
	{
		this.m = m;
		queue = new LinkedBlockingQueue<GameCommand>();
	}
	
	/*
	 * (non-Javadoc)
	 * @see controller.AbstractDispatcher#dispatchCommand()
	 * 
	 * This method calls take() on the blocking queue, which
	 * will wait() the queue object if no commands are available 
	 */
	public void dispatchCommand() throws InterruptedException
	{
		m.accept(queue.take());
		System.out.println("[CONTROLLER] ModelDispatcher successfully completed " +
				"GameCommand dispatch.");
	}

	/*
	 * (non-Javadoc)
	 * @see controller.AbstractDispatcher#export(model.GameCommand)
	 * 
	 * This method calls put() on the blocking queue, which will
	 * wait() on the queue object if no buffer space is available
	 */
	public void export(GameCommand gc) throws InterruptedException
	{
		queue.put(gc);
		System.out.println("[CONTROLLER] ModelDispatcher sucessfully inserted GameCommand into " +
				"Command Queue.");
	}
	
	public boolean isEmpty()
	{
		return queue.isEmpty();
	}
}
